1 module unde.games.dizzy.omega.animations.lava;
2 
3 import derelict.opengl3.gl;
4 import std.math;
5 import std.random;
6 import std.stdio;
7 import unde.games.object;
8 import unde.games.renderer;
9 import unde.global_state;
10 
11 class Lava:StaticGameObject
12 {
13     float x1, y1, z1;
14     float x2, y2, z2;
15 
16     enum G = 0.005;
17     enum SPEED = 0.05;
18 
19     float[3][3] bubbles;
20     float[3][3][3] subbubbles;
21     
22     float[3] sizes;
23     float[3][3] subsizes;
24 
25     float[3][3] speed;
26     float[3][3][3] subspeed;
27 
28     Random rnd;
29     
30     this(MainGameObject root, float[3] c1, float[3] c2, Random _rnd)
31     {
32         x1 = c1[0];
33         y1 = c1[1];
34         z1 = c1[2];
35         
36         x2 = c2[0];
37         y2 = c2[1];
38         z2 = c2[2];
39 
40         rnd = _rnd;
41         
42         models["lava-bubble"] = root.models["lava-bubble"];
43         super(root);
44     }
45 
46     override void draw(GlobalState gs)
47     {
48         if (root.scrx < x1 - 30.0 ||
49             root.scrx > x2 + 30.0 ||
50             root.scry < y1 - 18.0 ||
51             root.scry > y2 + 18.0) return;
52             
53         foreach (i, ref bubble; bubbles)
54         {
55             if (!isNaN(bubble[0]))
56             {
57                 glPushMatrix();
58                 glTranslatef(bubble[0], bubble[1], bubble[2]);
59                 glScalef(sizes[i], sizes[i], sizes[i]);
60                 recursive_render(gs, models["lava-bubble"]);
61                 glPopMatrix();
62             }
63         }
64 
65         foreach (i, ref subbubblez; subbubbles)
66         {
67             foreach (j, ref subbubble; subbubblez)
68             {
69                 if (!isNaN(subbubble[0]))
70                 {
71                     glPushMatrix();
72                     glTranslatef(subbubble[0], subbubble[1], subbubble[2]);
73                     glScalef(subsizes[i][j], subsizes[i][j], subsizes[i][j]);
74                     recursive_render(gs, models["lava-bubble"]);
75                     glPopMatrix();
76                 }
77             }
78         }
79     }
80     
81     override bool tick(GlobalState gs)
82     {
83         if (root.scrx < x1 - 30.0 ||
84             root.scrx > x2 + 30.0 ||
85             root.scry < y1 - 18.0 ||
86             root.scry > y2 + 18.0) return true;
87             
88         foreach (i, ref bubble; bubbles)
89         {
90             if (!isNaN(bubble[0]))
91             {
92                 if (bubble[1] > y2)
93                 {
94                     foreach (j, ref subbubble; subbubbles[i])
95                     {
96                         subbubble[0..3] = bubble[0..3];
97                         subsizes[i][j] = uniform(sizes[i]*0.1, sizes[i]*0.5, rnd);
98                         subspeed[i][j][0] = uniform(-SPEED, SPEED, rnd);
99                         subspeed[i][j][1] = speed[i][1];
100                         subspeed[i][j][2] = uniform(-SPEED, SPEED, rnd);
101                     }
102                     bubble[0] = float.nan;
103                 }
104                 else
105                 {
106                     //writefln("%s: %s - %s", i, bubble, speed[i]);
107                     bubble[0..3] += speed[i][0..3];
108                 }
109             }
110         }
111 
112         foreach (i, ref subbubblez; subbubbles)
113         {
114             int isnans;
115             foreach (j, ref subbubble; subbubblez)
116             {
117                 if (!isNaN(subbubble[0]))
118                 {
119                     subbubble[0..3] += subspeed[i][j][0..3];
120                     subspeed[i][j][1] -= G;
121                     if (subspeed[i][j][1] < -SPEED) subspeed[i][j][1] = -SPEED;
122 
123                     if (subbubble[1] < y2 ||
124                         subbubble[0] < x1 || subbubble[0] > x2 ||
125                         subbubble[2] < z1 || subbubble[2] > z2)
126                     {
127                         subbubble[0] = float.nan;
128                     }
129                 }
130 
131                 if (isNaN(subbubble[0]) && isNaN(bubbles[i][0]))
132                 {
133                     isnans++;
134                 }
135             }
136         
137             if (isnans == subbubblez.length)
138             {
139                 bubbles[i][0] = uniform(x1, x2, rnd);
140                 bubbles[i][1] = y1;
141                 bubbles[i][2] = uniform(z1, z2, rnd);
142 
143                 sizes[i] = uniform(0.5, 1.0, rnd);
144 
145                 speed[i][0] = 0.0;
146                 speed[i][1] = uniform(0.5*SPEED, 1.5*SPEED, rnd);
147                 speed[i][2] = 0.0;
148             }
149         }
150         
151         return true;
152     }
153 }